package cn.biplam.back.bean.systemManage.privi;

import java.io.Serializable;
import java.util.ArrayList;

import cn.biplam.back.bean.tree.IndexTableExtImpl;
import cn.biplam.back.sql.dml.Update;
import cn.biplam.common.bean.sqlengine.Sql;
import cn.biplam.common.bean.systemManage.privi.RoleManageBean;
import cn.biplam.common.bean.tree.IndexTableExt;
import cn.biplam.common.bean.tree.IndexTableSimple;
import cn.biplam.common.client.DataFilter;
import cn.biplam.common.client.Operator;
import cn.biplam.common.client.OperatorResult;
import cn.biplam.common.opcode.SysManageCode.RolePriviOptCode;
import cn.biplam.common.opcode.SysManageCode.UserRoleOptCode;
import cn.biplam.common.struc.SysStruc.PriviStruc;
import cn.biplam.common.struc.SysStruc.RoleIndexStruc;
import cn.biplam.common.struc.SysStruc.RolePriviStruc;
import cn.biplam.common.struc.SysStruc.Role_Privi_Flag;
import cn.biplam.common.struc.SysStruc.UserRoleStruc;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;

/**
 *  用户角色管理操作
 * @author XiaoRuxing Dec 4, 200911:55:27 AM
 * @version 1.0
 */
public class RoleManageBeanImp extends RoleManageBean implements Serializable{

	/**  */
	private static final long serialVersionUID = 9027973201L;
	private String tableName = RoleIndexStruc.Table_Name;

	public RoleManageBeanImp(String userId){
		this.userId = userId;
	}
	
	/**
	 *  删除角色<BR>
	 *  级联操作:删除用户角色,删除用户权限
	 * @param roleId 角色ID
	 * @param getSql 是否获取SQL
	 * @return  getSql=true:返回删除角色的SQL<BR>
	 *          getSql=false:执行删除角色,返回是否删除成功<BR>
	 * @throws ErrorMessage 
	 */
	public OperatorResult delRole(String roleId,boolean getSql) throws ErrorMessage {
		ArrayList<String> sql = new ArrayList<String>();
		
		//1 删除当前角色对应的所有角色权限
		deleteRolePriviByRoleId(sql, roleId);
		
		//2 删除当前角色对应的用户角色关系(在删除用户角色关系中级联删除用户权限)
		delRoleUser(roleId, sql);
		
		//3 删除当前角色
		sql.addAll(IndexTableSimple.getNewInstance(userId, tableName).delete(roleId, true).getSqls());
		if(getSql){
			return this.setSql(sql);
		}else{
			return this.doingDML(sql);
		}
	}

	/**
	 *  删除角色目录<BR>
	 *  操作:删除当前主题下所有子目录和角色
	 * @param roleThemeId 角色目录ID
	 * @return 删除是否成功
	 * @throws ErrorMessage 
	 */
	@Override
	public OperatorResult delRoleTheme(String roleThemeId) throws ErrorMessage {
		//删除目录下所有子节点
		ArrayList<String>  childList = IndexTableExt.getNewInstance(userId, tableName).getChilds(roleThemeId, dbResource, null);
		ArrayList<String> sql = new ArrayList<String>();
		for(String child:childList){
			sql.addAll(this.delRole(child,true).getSqls());
		}
		//删除当前目录
		sql.addAll(IndexTableSimple.getNewInstance(userId, tableName).delete(roleThemeId, true).getSqls());
		return this.doingDML(sql);
	}

	/**
	 *  添加角色权限
	 * @param roleId  角色ID
	 * @param priviId 权限ID
	 * @return 添加结果
	 * @throws ErrorMessage 
	 */
	@Override
	public OperatorResult addRolePrivi(String roleId, String priviId) throws ErrorMessage {
		
		ArrayList<String> sql = new ArrayList<String>();
		//权限索引表操作对象
		IndexTableExtImpl indexOpt = new IndexTableExtImpl(userId,PriviStruc.Table_Name);
		
		//1.将当前权限的所有上级权限授予给角色(非完全权限)
		  //1.1 获取所有上级权限列表
			ArrayList<String> parentPrivs = indexOpt.findPath(priviId, null);
			for(String parent:parentPrivs){
				String priviType = null;
				priviType = this.rolePriviType(roleId, parent);
				//1.2 如果角色具有上级权限(非完全权限 or 完全)不授权;否则,授权当前角色具有上级权限(为非完全权限)
				if(priviType==null){
					this.grantPriviToRole(sql, roleId, parent, Role_Privi_Flag.NORMAL.toString());
				}
			}
			
		//2.授予角色当前权限(完全权限)
			String curPriviType = rolePriviType(roleId, priviId);
			if(curPriviType!=null){
				//如果当前角色权限已经存在,设置角色权限标志为完全权限;
				this.setRolePriviType(roleId, priviId, Role_Privi_Flag.SUPPER.toString(), sql);
			}else{
				 //否则,授予角色当前权限(完全权限);
				this.grantPriviToRole(sql, roleId, priviId, Role_Privi_Flag.SUPPER.toString());
			}
		  
		//3.授予角色当前权限的所有下级权限(完全权限)
		   //获取所有下级权限列表
			ArrayList<String> childPrivis = indexOpt.getChilds(priviId, null, null);
			//遍历下级权限授予角色
			for(String childPrivi:childPrivis){
				String chidPrivType = rolePriviType(roleId, childPrivi);
				if(chidPrivType==null){
					//如果当前角色不拥有当前下级权限:授权当前角色具有下级权限(完全权限)
					this.grantPriviToRole(sql, roleId, childPrivi, Role_Privi_Flag.SUPPER.toString());
				}else if(chidPrivType.equals(Role_Privi_Flag.NORMAL.toString())){
					//如果当前下级权限已经存在且为非完全权限:更新标志位为完全权限;
					this.setRolePriviType(roleId, childPrivi, Role_Privi_Flag.SUPPER.toString(), sql);
				}
			}
		return this.doingDML(sql);
	}

	/**
	 *  删除角色权限(级联删除角色对应用户权限),删除当前角色权限的所有下级角色权限<BR>
	 *  如果角色权限标志不是完全拥有,禁止删除操作(由界面控制)<BR>
	 *  如果角色拥有当前权限父权限的完全权限在删除父权限前不能删除当前权限(由界面用控制)
	 * @param rolePriviId  角色权限ID
	 * @param getSql       是否获取SQL
	 * @return 根据getSql值返回<BR>
	 *       true:返回删除角色权限SQL,false:执行删除,返回删除是否成功
	 * @throws ErrorMessage 
	 */
	@Override
	public OperatorResult delRolePrivi(String rolePriviId,boolean getSql) throws ErrorMessage {
		ArrayList<String> sql = new ArrayList<String>();
		//查询当前角色权限对应的角色ID和权限ID
		OperatorResult rolePrivi = this.queryRolePriviById(rolePriviId);
		if(!TOOLS.exist(rolePrivi))throw new ErrorMessage(" RolePrivi do not eixst at delete RolePrivi!");
		String roleId = rolePrivi.getValue(RolePriviStruc.ROLE_ID);//角色ID
		String priviId = rolePrivi.getValue(RolePriviStruc.PRIVI_ID);//权限ID
		
		//获取当前角色权限所有下级权限
		ArrayList<String> childPrivis = new IndexTableExtImpl(userId,PriviStruc.Table_Name).
											getChilds(priviId, dbResource, null);
		//删除角色和下级权限对应权限
		for(String privi: childPrivis){
			OperatorResult curRolePrivi = this.queryRolePriviByRoleAndPriv(roleId, privi);
			if(TOOLS.exist(curRolePrivi)){
				this.delRolePriviNoChildPrivi(curRolePrivi.getValue(RolePriviStruc.ID),sql);
			}
		}
		
		//删除当前角色权限
		delRolePriviNoChildPrivi(rolePriviId,sql);
		if(getSql){
			this.setSql(sql);
			return this.result;
		}else{
			return this.doingDML(sql);
		}
	}
	
	/**
	 *  删除角色权限,不级联操作用户角色权限子权限(级联删除角色对应用户权限)<BR>
	 *  用于删除权限时级联删除(由于删除权限时已经级联删除所有下级权限)
	 * @param rolePriviId 角色权限ID
	 * @throws ErrorMessage 
	 */
	protected void delRolePriviNoChildPrivi(String rolePriviId,ArrayList<String> sql) throws ErrorMessage{
		//删除角色权限
		delRolePrivi(sql, rolePriviId);
		OperatorResult rolePrivi = this.queryRolePriviById(rolePriviId);
		//删除拥有当前角色的用户权限
		delRoleUserPrivi(
				rolePrivi.getValue(RolePriviStruc.ROLE_ID), //角色ID
				rolePrivi.getValue(RolePriviStruc.PRIVI_ID), //角色ID
				sql);
	}
	
	/**
	 *  授予单个权限给角色
	 * @param sql
	 * @param roleId     角色ID
	 * @param priviId    权限ID
	 * @param supperFlag 完全权限标志
	 * @throws ErrorMessage
	 */
	protected void grantPriviToRole(ArrayList<String> sql,
			String roleId, 
			String priviId,
			String supperFlag) throws ErrorMessage{
		//1 将权限赋予角色
		DataFilter filter = new DataFilter();
		filter.put(RolePriviStruc.ROLE_ID,roleId);
		filter.put(RolePriviStruc.PRIVI_ID,priviId);
		filter.put(RolePriviStruc.SUPPER_FLAG,supperFlag);
		sql.addAll(Operator.get(RolePriviOptCode.Insert, userId, filter,true).getSqls());
		//2 授予与角色有关的用户权限(授予前判断角色是否已经有此权限，有则不用授权)
		//获取与拥有当前角色的用户
		DataFilter urFilter = new DataFilter();
		urFilter.put(UserRoleStruc.ROLE_ID, roleId);
		OperatorResult roleUsers = Operator.get(UserRoleOptCode.Query_By_RoleId, userId, urFilter);
		if(TOOLS.exist(roleUsers)){
			UserManageBeanImp userMange = new UserManageBeanImp(userId);
			String curUser = null;
			//授予拥有角色的用户权限
			do{
				curUser = roleUsers.getValue(UserRoleStruc.USER_ID);
				userMange.grantPriviToUser(sql, priviId, curUser);
			}while(roleUsers.next());
		}
	}
	
	/**
	 *  查询指定角色是否具有权限
	 * @param roleId  角色ID
	 * @param priviId 权限ID
	 * @return 角色具有权限:返回角色权限类型(完全权限 or 部分权限)<BR>
	 *         角色不具有权限: 返回NULL
	 * @throws ErrorMessage 
	 */
	private String rolePriviType(String roleId, String priviId) throws ErrorMessage{
		//获取角色权限
		OperatorResult rs = this.queryRolePriviByRoleAndPriv(roleId, priviId);
		if(TOOLS.exist(rs)){
			return rs.getValue(RolePriviStruc.SUPPER_FLAG);
		}else{
			return null;
		}
	}
	
	/**
	 *  根据角色权限ID查询角色权限
	 */
	private OperatorResult queryRolePriviById(String rolePriviId) throws ErrorMessage{
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(RolePriviStruc.Table_Name);
		sp.append(" where ");
		sp.append(RolePriviStruc.ID);
		sp.append("='");
		sp.append(rolePriviId);
		sp.append("'");
		//获取角色权限
		OperatorResult rs = this.doingSelect(new Sql(sp.toString()));
		return rs;
	}
	
	/**
	 *  根据角色ID和权限ID查询角色权限
	 */
	private OperatorResult queryRolePriviByRoleAndPriv(String roleId,String priviId) throws ErrorMessage{
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(RolePriviStruc.Table_Name);
		sp.append(" where ");
		sp.append(RolePriviStruc.ROLE_ID);
		sp.append("='");
		sp.append(roleId);
		sp.append("' and ");
		sp.append(RolePriviStruc.PRIVI_ID);
		sp.append("='");
		sp.append(priviId);
		sp.append("'");
		//获取角色权限
		OperatorResult rs = this.doingSelect(new Sql(sp.toString()));
		return rs;
	}
	
	/**
	 * @return 设置角色权限类型(完全权限、非完全权限)
	 * @throws ErrorMessage 
	 */
	private void setRolePriviType(String roleId, 
			String priviId, 
			String rolePriviType,
			ArrayList<String> sql) throws ErrorMessage{
		Update insert = new Update(RolePriviStruc.Table_Name);
		insert.putStringFieldDenyNull(RolePriviStruc.SUPPER_FLAG, rolePriviType);
		StringBuilder sp = new StringBuilder();
		sp.append(RolePriviStruc.ROLE_ID+"='"+roleId+"' and ");
		sp.append(RolePriviStruc.PRIVI_ID+"='"+priviId+"'");
		insert.setWhere(sp.toString());
		sql.add(insert.getSimpleSql());
	}
	
	/**
	 *  根据角色ID删除角色权限(未级联删除角色对应用户权限)<BR>
	 *  用户删除角色级联操作
	 * @param roleId 角色ID
	 * @throws ErrorMessage 
	 */
	private void deleteRolePriviByRoleId(ArrayList<String> sql,String roleId) throws ErrorMessage{
		//获取当前角色的所有角色权限
		DataFilter filter = new DataFilter();
		filter.put(RolePriviStruc.ROLE_ID ,roleId);
		OperatorResult rolePrivis = Operator.get(RolePriviOptCode.Query_By_Role_ID, userId, filter);
		//删除角色权限
		if(TOOLS.exist(rolePrivis)){
			do{
				delRolePrivi(sql, rolePrivis.getValue(RolePriviStruc.ID));
			}while(rolePrivis.next());
		}
	}
	
	/**
	 *  删除角色权限(未做级联操作,只是操作角色权限表)
	 * @param rolePriviId 角色权限ID
	 * @throws ErrorMessage 
	 */
	private void delRolePrivi(ArrayList<String> sql ,String rolePriviId) throws ErrorMessage{
		//删除角色权限
		DataFilter filter = new DataFilter(rolePriviId);
		sql.addAll(Operator.get(RolePriviOptCode.Delete, userId, filter,true).getSqls());
	}
	
	/**
	 *  删除当前角色对应的用户角色关系(在删除用户角色关系中级联删除用户权限)
	 * @param roleId 角色ID
	 * @param sql    sql语句
	 * @throws ErrorMessage
	 */
	private void delRoleUser(String roleId,ArrayList<String> sql) throws ErrorMessage{
		DataFilter roleFilter = new DataFilter();
		roleFilter.put(UserRoleStruc.ROLE_ID,roleId);
		OperatorResult roleUsers = Operator.get(UserRoleOptCode.Query_By_RoleId, userId, roleFilter);
		//删除用户角色关系
		if(TOOLS.exist(roleUsers)){
			UserManageBeanImp userManage = new UserManageBeanImp(userId);
			String userRoleId = null;
			String curUser = null;
			do{
				userRoleId = roleUsers.getValue(UserRoleStruc.USER_ROLE_ID);
				curUser = roleUsers.getValue(UserRoleStruc.USER_ID);
				userManage.delUserRole(userRoleId, curUser, roleId, sql);
			}while(roleUsers.next());
		}
	}
	
	/**
	 *  获取用户在拥有的角色中是否只有指定角色拥有当前权限
	 * @throws ErrorMessage 
	 */
	private boolean getUserOnePrivi(String userId,String priviId,String roleId) throws ErrorMessage{
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(UserRoleStruc.Table_Name);
		sp.append(" a join "+RolePriviStruc.Table_Name+" b ");
		sp.append(" on a."+UserRoleStruc.ROLE_ID+"=b."+RolePriviStruc.ROLE_ID);
		sp.append(" where ");
		sp.append(" a."+UserRoleStruc.USER_ID+"='"+userId+"'");
		sp.append(" and b."+RolePriviStruc.ROLE_ID+"='"+roleId+"'");
		sp.append(" and b."+RolePriviStruc.PRIVI_ID+"='"+priviId+"'");
		OperatorResult rs = this.doingSelect(new Sql(sp.toString()));
		if(TOOLS.exist(rs)){
			return rs.size()==1;
		}
		return false;
	}
	
	/**
	 *  拥有当前角色的指定权限的用户权限(在删除用户角色关系中级联删除用户权限)
	 * @param roleId 角色ID
	 * @param priviId 权限ID
	 * @param sql    sql语句
	 * @throws ErrorMessage
	 */
	private void delRoleUserPrivi(String roleId,String priviId,ArrayList<String> sql) throws ErrorMessage{
		//获取拥有当前角色的用户ID
		DataFilter roleFilter = new DataFilter();
		roleFilter.put(UserRoleStruc.ROLE_ID,roleId);
		OperatorResult roleUsers = Operator.get(UserRoleOptCode.Query_By_RoleId, userId, roleFilter);
		//删除用户权限
		if(TOOLS.exist(roleUsers)){
			UserManageBeanImp userManage = new UserManageBeanImp(userId);
			String curUser = null;
			do{
				//获取用户是否只在当前角色中拥有此权限,如果是删除当前用户权限,否则不删除
				curUser = roleUsers.getValue(UserRoleStruc.USER_ID);
				if(getUserOnePrivi(curUser, priviId, roleId)){
					userManage.delUserPrivi(sql, curUser, priviId);
				}
			}while(roleUsers.next());
		}
	}
}
